package com.diaohw.platform.remote.ws.netty;

import com.diaohw.platform.common.util.JsonUtil;
import com.diaohw.platform.common.util.ThreadUtil;
import com.diaohw.platform.utility.netty.NettyClient;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service
@ChannelHandler.Sharable
@ConditionalOnProperty("platform.remote.ws.netty.enable")
public class NettyClientService extends SimpleChannelInboundHandler<String> {

    @Resource
    private WsNettyProperties properties;
    private NettyClient client;

    private final static Map<String, CountDownLatch> locks = new ConcurrentHashMap<>();
    private final static Map<String, NettyMsgVO> msgs = new ConcurrentHashMap<>();

    @PostConstruct
    public void init() {
        client = new NettyClient(properties.getPort(), properties.getHost());
        client.connect(this);
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, String msg) {

        // 打印接收到的消息
        NettyMsgVO object = JsonUtil.toBean(msg, NettyMsgVO.class);
        if (locks.containsKey(object.getId())) {
            msgs.put(object.getId(), object);
            locks.get(object.getId()).countDown();
        }
    }

    /**
     * 发送消息
     *
     * @return 回调数据
     */
    public NettyMsgVO sendMessage(NettyMsgDTO message) {
        return sendMessage(message, 1, TimeUnit.SECONDS);
    }

    /**
     * 发送消息
     *
     * @param timeout 超时时间
     * @param unit    时间单位
     * @return 回调数据
     */
    public NettyMsgVO sendMessage(NettyMsgDTO message, int timeout, TimeUnit unit) {
        if (!message.isCallback()) {
            client.sendMessage(JsonUtil.toJsonEmpty(message));
            return null;
        }
        CountDownLatch latch = new CountDownLatch(1);
        locks.put(message.getMsgId(), latch);
        client.sendMessage(JsonUtil.toJsonEmpty(message));
        ThreadUtil.await(latch, timeout, unit);
        locks.remove(message.getMsgId());
        return msgs.remove(message.getMsgId());
    }

    /**
     * 发送消息，没有回调
     */
    public void sendMessageNoCallback(NettyMsgDTO message) {
        client.sendMessage(JsonUtil.toJsonEmpty(message));
    }

}
